package org.budo.weixin.qiye.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import org.budo.support.lang.util.StringUtil;
import org.budo.support.slf4j.Slf4j;
import org.budo.weixin.qiye.WeixinSaasCallBackInfo;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.slf4j.Logger;

public class WeixinSaasUtil {
    private static final Logger log = Slf4j.getLogger();

    public static WeixinSaasCallBackInfo getCallbcakInfo(String decryptMessage) {
        log.info("start parse callbackinfo:");
        log.info(decryptMessage);

        /**
         * 下面内容未做处理 <FromUserName><![CDATA[cj]]></FromUserName> <CreateTime>1482317129</CreateTime> <MsgType><![CDATA[event]]></MsgType> <AgentID>25</AgentID> <Event><![CDATA[subscribe]]></Event> <EventKey><![CDATA[]]></EventKey> </xml>
         **/
        try {

            Document document = Jsoup.parse(decryptMessage);
            Elements xml = document.select("xml");

            String suiteId = xml.select("SuiteId").text();
            String infoType = xml.select("InfoType").text();
            String string_time = StringUtil.isEmpty(xml.select("TimeStamp").text()) ? "0" : xml.select("TimeStamp").text();
            Long timeStamp = Long.valueOf(string_time);
            WeixinSaasCallBackInfo weixinSaasCallBackInfo = new WeixinSaasCallBackInfo(suiteId, timeStamp, infoType);

            switch (infoType) {
            case WeixinSaasCallBackInfo.SUITE_TICKET:
                String suiteTicket = xml.select("SuiteTicket").text();
                weixinSaasCallBackInfo.setSuiteTicket(suiteTicket);
                break;
            case WeixinSaasCallBackInfo.CREATE_AUTH:
                String authCode = xml.select("AuthCode").text();
                weixinSaasCallBackInfo.setAuthCode(authCode);
                break;
            case WeixinSaasCallBackInfo.CHANGE_AUTH:
                String authCorpId1 = xml.select("AuthCorpId").text();
                weixinSaasCallBackInfo.setAuthCorpId(authCorpId1);
                break;
            case WeixinSaasCallBackInfo.CANCEL_AUTH:
                String authCorpId2 = xml.select("AuthCorpId").text();
                weixinSaasCallBackInfo.setAuthCorpId(authCorpId2);
                break;
            case WeixinSaasCallBackInfo.CONTACT_SYNC:
                String authCorpId3 = xml.select("AuthCorpId").text();
                String seq = xml.select("Seq").text();
                weixinSaasCallBackInfo.setAuthCorpId(authCorpId3);
                weixinSaasCallBackInfo.setSeq(Integer.valueOf(seq));
                break;
            }

            return weixinSaasCallBackInfo;
        } catch (Throwable e) {
            log.error("fromXml error " + e, e);
            throw new RuntimeException(e);
        }
    }

    public static WeixinSaasCallBackInfo getDecryptCallbcakInfo(String postData, String msgSignature, String timestamp, String nonce, String suite_token, String suite_encoding_aes_key, String corpid) {
        try {
            String typeName = "com.qq.weixin.mp.aes.WXBizMsgCrypt";
            Class<?> type = Class.forName(typeName);

            Constructor<?> constructor = type.getConstructor(String.class, String.class, String.class);
            Object wxBizMsgCrypt = constructor.newInstance(suite_token, suite_encoding_aes_key, corpid);

            Method method = type.getMethod("DecryptMsg", String.class, String.class, String.class, String.class);
            String decryptMsg = (String) method.invoke(wxBizMsgCrypt, msgSignature, timestamp, nonce, postData);

            return getCallbcakInfo(decryptMsg);
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }

}
